#include <math.h>
#include <iostream>
#include <set>

using namespace std;

template<typename Container>
void display(Container & con){
    for(auto &ele:con){
        cout << "("<< ele.getx() << ","
            << ele.gety()<< ")" << "   ";
    }
    cout << endl;;

}

class Point{
public:
    Point(int x,int y)
        :_x(x)
         ,_y(y)
    {

    }

    double getDistance()const
    {
        return hypot(_x,_y);
    }

    int getx() const
    {
        return _x;
    }

    int gety() const
    {
        return _y;
    }

    friend bool operator<(const Point &lhs,const Point &rhs);
private:
    int _x;
    int _y;
};

namespace std{
template<>
    struct less<Point>
    {
        bool operator()(const Point &lhs,const Point &rhs)const 
        {
            cout << "namespace"<< endl;
            if(lhs.getDistance() < rhs.getDistance()){
                return true;
            }else if(lhs.getDistance() == rhs.getDistance())
            {
                if(lhs.getx() < rhs.getx()){
                    return true;
                }else if(lhs.getx() == rhs.getx())
                {
                    if(lhs.gety() < rhs.gety()){
                        return true;
                    }else{
                        return false;
                    }
                }else{
                    return false;
                }
            }else{
                return false;   
            }
        }

    };

}

class setCompare
{
public:
    bool operator()(const Point &lhs,const Point &rhs)const
    {
        cout << "class setCompare"<< endl;
        if(lhs.getDistance() < rhs.getDistance()){
            return true;
        }else if(lhs.getDistance() == rhs.getDistance())
        {
            if(lhs.getx() < rhs.getx()){
                return true;
            }else if(lhs.getx() == rhs.getx())
            {
                if(lhs.gety() < rhs.gety()){
                    return true;
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }else{
            return false;   
        }
    }

};



bool operator<(const Point &lhs,const Point &rhs)
{
    cout << "operator<"<< endl;
    if(lhs.getDistance() < rhs.getDistance()){
        return true;
    }else if(lhs.getDistance() == rhs.getDistance())
    {
        if(lhs.getx() < rhs.getx()){
            return true;
        }else if(lhs.getx() == rhs.getx())
        {
            if(lhs.gety() < rhs.gety()){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }else{
        return false;   
    }
}

void test(){
    set<Point,setCompare> sec = {
        Point(1,2),
        Point(-1,2),
        Point(1,-2),
        Point(3,2),
        Point(6,2),
        Point(1,2),
        Point(-1,-2)
    };
    display(sec);

}

int main()
{
    test();
    return 0;
}

